<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Using telnet to manipulate a twisted server</title></head>
<body>
<h1>Using telnet to manipulate a twisted server</h1>

<p>To start things off, we're going to create a simple server that just
gives you remote access to a Python interpreter. We will use a telnet client
to access this server.</p>

<p>Run <code class="shell">mktap telnet -p 4040 -u admin -w admin</code> at
your shell prompt. If you list the contents of your current directory,
you'll notice a new file -- <code>telnet.tap</code>.  After you do this, run
<code class="shell">twistd -f telnet.tap</code>. Since the Application has a
telnet server that you specified to be on port 4040, it will start listening
for connections on this port. Try connecting with your favorite telnet
utility to 127.0.0.1 port 4040.</p>

<pre class="shell">
$ <em>telnet localhost 4040</em>
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

twisted.manhole.telnet.ShellFactory
Twisted 1.1.0
username: <em>admin</em>
password: <em>admin</em>
&gt;&gt;&gt;
</pre>

<p>Now, you should see a Python prompt --
<code>&gt;&gt;&gt;</code>. You can type any valid Python code
here. Let's try looking around.</p>

<pre class="python-interpreter">
&gt;&gt;&gt; <em>dir()</em>
['__builtins__']
</pre>

<p>Ok, not much. let's play a little more:</p>
<pre class="python-interpreter">
&gt;&gt;&gt; <em>import __main__</em>
&gt;&gt;&gt; <em>dir(__main__)</em>
['__builtins__', '__doc__', '__name__', 'os', 'run', 'string', 'sys']

&gt;&gt;&gt; <em>service</em>
&lt;twisted.application.internet.TCPServer instance at 0x10270f48&gt;
&gt;&gt;&gt; <em>service._port</em>
&lt;twisted.manhole.telnet.ShellFactory on 4040&gt;
&gt;&gt;&gt; <em>service.parent</em>
&lt;twisted.application.service.MultiService instance at 0x1024d7a8&gt;
</pre>

<p>The service object is the service used to serve the telnet shell,
and that it is listening on port 4040 with something called a
<code class="API" base="twisted.manhole.telnet">ShellFactory</code>. 
Its parent is a <code class="python">twisted.application.service.MultiService</code>,
a collection of services. We can keep getting the parent attribute
of services until we hit the root of all services in this tap.</p>

<p>As you can see, this is quite useful - we can introspect a
running process, see the internal objects, and even change
their attributes. We can add telnet support to existing
tap like so: <code class="shell">mktap --append=foo.tap telnet -p 4040 -u user -w pass</code>. 
The telnet server can of coursed be used from straight Python code as well. You can
see how to do this by reading the code for <code class="API">twisted.tap.telnet</code>.</p>

<p>A final note - if you want access to be more secure, you can even
have the telnet server use SSL. Assuming you have the appropriate
certificate and private key files, you can <code class="shell">mktap
telnet -p ssl:443:privateKey=mykey.pem:certKey=cert.pem -u admin -w
admin</code>.  See <code
class="API">twisted.application.strports</code> for more examples of
options for listening on a port.</p>

</body></html>
